package edu.gzc.nio.nonblockingnio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * @Description:
 * @Author: guozongchao
 * @Date: 2021/1/7 22:11
 */
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel ssChannel = ServerSocketChannel.open();

        //切换到非阻塞模式
        ssChannel.configureBlocking(false);

        //绑定连接
        ssChannel.bind(new InetSocketAddress(9898));

        //获取选择器
        Selector selector = Selector.open();

        //将通道注册到选择器中,并指定“监听接收事件”
        ssChannel.register(selector, SelectionKey.OP_ACCEPT);

        //通过选择器，轮询获取选择器上已经“准备就绪”的事件
        while (selector.select() > 0) {
            //获取当前选择器中所有注册的“选择键（已就绪的监听事件）”
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            //迭代获取
            while (iterator.hasNext()) {
                //获取准备“就绪”的事件
                SelectionKey sk = iterator.next();

                //判断是什么事件就绪
                if (sk.isAcceptable()) {
                    //获取客户端通道
                    SocketChannel sChannel = ssChannel.accept();

                    //并切换非阻塞模式
                    sChannel.configureBlocking(false);

                    //将该通道注册到选择器上
                    sChannel.register(selector, SelectionKey.OP_READ);
                } else if (sk.isReadable()) {
                    //获取当前选择器上“读就绪”状态的通道
                    SocketChannel sChannel = (SocketChannel) sk.channel();

                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int len = 0;
                    while ((len = sChannel.read(buffer)) >0) {
                        buffer.flip();
                        System.out.println(new String(buffer.array(), 0, len));
                        buffer.clear();
                    }
                }
                //注意，需要取消选择键
                iterator.remove();
            }
        }
    }
}
